package cn.turboinfo.fuyang.api.domain.share.usecase.staff;

import cn.turboinfo.fuyang.api.domain.common.service.confidence.ConfidenceCodeService;
import cn.turboinfo.fuyang.api.domain.common.service.dictconfig.DictConfigItemService;
import cn.turboinfo.fuyang.api.domain.common.service.staff.HousekeepingStaffService;
import cn.turboinfo.fuyang.api.domain.common.usecase.AbstractUseCase;
import cn.turboinfo.fuyang.api.domain.util.IdCardUtils;
import cn.turboinfo.fuyang.api.domain.util.PhoneUtils;
import cn.turboinfo.fuyang.api.entity.common.constant.DictConstants;
import cn.turboinfo.fuyang.api.entity.common.pojo.confidence.ConfidenceCode;
import cn.turboinfo.fuyang.api.entity.common.pojo.dictconfig.DictConfigItem;
import cn.turboinfo.fuyang.api.entity.common.pojo.staff.HousekeepingStaff;
import cn.turboinfo.fuyang.api.entity.common.pojo.staff.HousekeepingStaffCreator;
import cn.turboinfo.fuyang.api.entity.common.pojo.staff.HousekeepingStaffUpdater;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import net.sunshow.toolkit.core.qbean.helper.component.request.QBeanCreatorHelper;
import net.sunshow.toolkit.core.qbean.helper.component.request.QBeanUpdaterHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Positive;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 添加家政人员
 */
@Slf4j
@RequiredArgsConstructor
@Component
public class ShareAddStaffUseCase extends AbstractUseCase<ShareAddStaffUseCase.InputData, ShareAddStaffUseCase.OutputData> {

    private final HousekeepingStaffService housekeepingStaffService;

    private final ConfidenceCodeService confidenceCodeService;

    private final DictConfigItemService dictConfigItemService;

    @Override
    protected OutputData doAction(InputData inputData) {

        Long companyId = inputData.getCompanyId();
        // 查询企业已存在列表
        List<HousekeepingStaff> housekeepingStaffList = housekeepingStaffService.findByCompanyId(companyId);
        Map<String, HousekeepingStaff> idCardStaffMap = housekeepingStaffList
                .stream()
                .collect(Collectors.toMap(HousekeepingStaff::getIdCard, item -> item));

        Map<String, HousekeepingStaff> mobileStaffMap = housekeepingStaffList
                .stream()
                .collect(Collectors.toMap(HousekeepingStaff::getContactMobile, item -> item));

        List<HousekeepingStaff> staffList = inputData.getStaffList();
        List<String> errorMsgList = new ArrayList<>();
        if (staffList != null && staffList.size() > 0) {
            staffList.forEach(item -> {
                if (!PhoneUtils.isValidPhoneNum(item.getContactMobile())) {
                    log.error("上传家政员信息错误，手机号不正确: {}", item.getContactMobile());
                    errorMsgList.add("手机号不正确: " + item.getContactMobile());
                    return;
                }
                if (!IdCardUtils.isValidIdCardNum(item.getIdCard())) {
                    log.error("上传家政员信息错误，身份证号不正确: {}", item.getContactMobile());
                    errorMsgList.add("身份证号不正确: " + item.getIdCard());
                    return;
                }

                // 校验手机号是否存在
                if (!mobileStaffMap.containsKey(item.getContactMobile())) {
                    Optional<HousekeepingStaff> housekeepingStaffOptional = housekeepingStaffService.findByMobile(item.getContactMobile());
                    if (housekeepingStaffOptional.isPresent()) {
                        log.error("上传家政员信息错误，手机号已存在: {}", item.getContactMobile());
                        errorMsgList.add("手机号已存在: " + item.getIdCard());
                        return;
                    }
                }

                if (!idCardStaffMap.containsKey(item.getIdCard())) {
                    Optional<HousekeepingStaff> housekeepingStaffOptional = housekeepingStaffService.findByIdCard(item.getIdCard());
                    if (housekeepingStaffOptional.isPresent()) {
                        log.error("上传家政员信息错误，身份证号已存在: {}", item.getIdCard());
                        errorMsgList.add("身份证号已存在: " + item.getIdCard());
                        return;
                    }
                }


                Map<String, DictConfigItem> staffTypeMap = dictConfigItemService.findAllDictConfigItem(DictConstants.DICT_KEY_STAFF_TYPE)
                        .stream()
                        .collect(Collectors.toMap(DictConfigItem::getItemValue, o -> o));

                if (!staffTypeMap.containsKey(item.getStaffType())) {
                    log.error("上传家政员信息错误，家政员类型不正确, 身份证号：{}, 家政员类型：{}", item.getIdCard(), item.getStaffType());
                    errorMsgList.add("家政员类型不正确: " + item.getStaffType());
                    return;
                }

                if (idCardStaffMap.containsKey(item.getIdCard())) {
                    HousekeepingStaff staff = idCardStaffMap.get(item.getIdCard());

                    if (mobileStaffMap.containsKey(item.getContactMobile())) {
                        if (staff.getContactMobile().equals(item.getContactMobile())) {
                            log.error("上传家政员信息错误，手机号已存在: {}", item.getContactMobile());
                            errorMsgList.add("手机号已存在: " + item.getIdCard());
                            return;
                        }
                    }

                    HousekeepingStaffUpdater.Builder builder = HousekeepingStaffUpdater.builder(staff.getId());

                    QBeanUpdaterHelper.copyPropertiesToUpdateBuilder(builder, HousekeepingStaffUpdater.class, item);

                    housekeepingStaffService.update(builder.build());
                } else {
                    HousekeepingStaffCreator.Builder builder = HousekeepingStaffCreator.builder();

                    QBeanCreatorHelper.copyPropertiesToCreatorBuilder(builder, HousekeepingStaffCreator.class, item);

                    // 生成放心码
                    ConfidenceCode confidenceCode = confidenceCodeService.tagging();

                    housekeepingStaffService.save(builder
                            .withCompanyId(companyId)
                            .withCode(confidenceCode.getId().toString())
                            .withGender(IdCardUtils.judgeGender(item.getIdCard()))
                            .withProvinceCode(IdCardUtils.getProvinceCode(item.getIdCard()))
                            .build());
                }
            });

            if (errorMsgList.size() > 0) {
                throw new RuntimeException(StringUtils.join(errorMsgList, " ,"));
            }

        }


        return OutputData.builder()
                .build();
    }

    @EqualsAndHashCode(callSuper = true)
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class InputData extends AbstractUseCase.InputData {

        @NotNull(
                message = "企业编码不能为空"
        )
        @Positive
        private Long companyId;

        @NotNull(
                message = "家政员不能为空"
        )
        private List<HousekeepingStaff> staffList;

    }

    @Getter
    @Setter
    @Builder
    public static class OutputData extends AbstractUseCase.OutputData {
    }
}
